//备注：拷贝代码请加上作者信息
//作者：王海涛
//邮箱：1126471088@qq.com
//版本：V0.2.1
/********************************************************
    说明：
    1、提供DMA实时状态。
    2、由外部配置DMA相关参数。
    3、支持查询DMA传输个数。
    4、支持手动关闭DMA。
    5、由外部提供DMA回调函数。
    6、支持DMA内存拷贝（自动锁定空闲通道，拷贝完后自动释放通道）。
    7、基于STM32F10X标准库V3.6.0
**********************************************************/

#ifndef __DMA_BSP_H__
#define __DMA_BSP_H__

#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_dma.h"

#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif

/*DMA信号源枚举*/
typedef enum
{
    Source_ADC1                        = DMA1_Channel1_BASE,//ADC1
    Source_TIM2_CH3                    = DMA1_Channel1_BASE,//定时器2通道3
    Source_TIM4_CH1                    = DMA1_Channel1_BASE,//定时器4通道1
    Source_SPI1_RX                     = DMA1_Channel2_BASE,//SPI1接收
    Source_USART3_TX                   = DMA1_Channel2_BASE,//串口3发送
    Source_TIM1_CH1                    = DMA1_Channel2_BASE,//定时器1通道1
    Source_TIM2_UP                     = DMA1_Channel2_BASE,//定时器2更新
    Source_TIM3_CH3                    = DMA1_Channel2_BASE,//定时器3通道3
    Source_SPI1_TX                     = DMA1_Channel3_BASE,//SPI1发送
    Source_USART3_RX                   = DMA1_Channel3_BASE,//串口3接收
    Source_TIM1_CH2                    = DMA1_Channel3_BASE,//定时器1通道2
    Source_TIM3_CH4_TIM3_UP            = DMA1_Channel3_BASE,//定时器3通道4或更新
    Source_SPI_I2S2_RX                 = DMA1_Channel4_BASE,//I2S2接收
    Source_USART1_TX                   = DMA1_Channel4_BASE,//串口1发送
    Source_I2C2_TX                     = DMA1_Channel4_BASE,//I2C2发送
    Source_TIM1_TX4_TIM1_TRIG_TIM1_COM = DMA1_Channel4_BASE,//定时器1TX4或触发或输出比较
    Source_TIM4_CH2                    = DMA1_Channel4_BASE,//定时器4通道2
    Source_SPI_I2S2_TX                 = DMA1_Channel5_BASE,//I2S2发送
    Source_USART1_RX                   = DMA1_Channel5_BASE,//串口1接收
    Source_I2C2_RX                     = DMA1_Channel5_BASE,//I2C2接收
    Source_TIM1_UP                     = DMA1_Channel5_BASE,//定时器1更新
    Source_TIM2_CH1                    = DMA1_Channel5_BASE,//定时器2通道1
    Source_TIM4_CH3                    = DMA1_Channel5_BASE,//定时器4通道3
    Source_USART2_RX                   = DMA1_Channel6_BASE,//串口2接收
    Source_I2C1_TX                     = DMA1_Channel6_BASE,//I2C1发送
    Source_TIM1_CH3                    = DMA1_Channel6_BASE,//定时器1通道3
    Source_TIM3_CH1_TIM3_TRIG          = DMA1_Channel6_BASE,//定时器3通道1或触发
    Source_USART2_TX                   = DMA1_Channel7_BASE,//串口2发送
    Source_I2C1_RX                     = DMA1_Channel7_BASE,//I2C1接收
    Source_TIM2_CH2_TIM2_CH4           = DMA1_Channel7_BASE,//定时器2通道2或通道4
    Source_TIM4_UP                     = DMA1_Channel7_BASE,//定时器4更新

    Source_SPI_I2S3_RX                 = DMA2_Channel1_BASE,//I2S3接收
    Source_TIM5_CH4_TIM5_TRIG          = DMA2_Channel1_BASE,//定时器5通道4或触发
    Source_TIM8_CH3_TIM8_UP            = DMA2_Channel1_BASE,//定时器8通道3或更新
    Source_SPI_I2S3_TX                 = DMA2_Channel2_BASE,//I2S3发送
    Source_TIM5_CH3_TIM5_UP            = DMA2_Channel2_BASE,//定时器5通道3或更新
    Source_TIM8_CH4_TIM8_TRIG_TIM8_COM = DMA2_Channel2_BASE,//定时器8通道4或触发或输出比较
    Source_UART4_RX                    = DMA2_Channel3_BASE,//串口4接收
    Source_TIM6_UP_DAC_Channel1        = DMA2_Channel3_BASE,//定时器6更新或DAC通道1
    Source_TIM8_CH1                    = DMA2_Channel3_BASE,//定时器8通道1
    Source_SDIO                        = DMA2_Channel4_BASE,//SDIO
    Source_TIM5_CH2                    = DMA2_Channel4_BASE,//定时器5通道2
    Source_TIM7_UP_DAC_Channel2        = DMA2_Channel4_BASE,//定时器7更新或DAC通道2
    Source_ADC3                        = DMA2_Channel5_BASE,//ADC3
    Source_UART4_TX                    = DMA2_Channel5_BASE,//串口4发送
    Source_TIM5_CH1                    = DMA2_Channel5_BASE,//定时器5通道1
    Source_TIM8_CH2                    = DMA2_Channel5_BASE,//定时器8通道2
}WHT_DMA_enum;

/*DMA状态枚举*/
typedef enum
{
    TRx_TC = 0,//传输完成
    TRx_HT = 1,//传输过半
    TRx_TE = 2,//传输错误
    TRx_TS = 3,//传输开始
}WHT_DMA_State_enum;

/*DMA信息结构体*/
typedef struct
{
    unsigned char Mount_Count;//通道挂载个数
    FlagStatus BSP_Mutex;     //驱动锁
    WHT_DMA_State_enum State; //传输状态
}WHT_DMA_Info_t;

/*DMA配置结构体*/
typedef struct
{
    WHT_DMA_enum Name;              //信号源
    DMA_InitTypeDef* DMA_InitStruct;//DMA初始化结构体
    void (*IT_Callback)(void);      //回调函数
    volatile WHT_DMA_Info_t* Info;  //DMA信息
    void* Private_Data;             //私有数据
}WHT_DMA_Config_t;

/*DMA回调函数结构体*/
typedef struct
{
    ErrorStatus (*WHT_Register)(const WHT_DMA_Config_t* config);        //注册
    void (*WHT_Config)(const WHT_DMA_Config_t* config);                 //每个设备可自行配置
    unsigned short (*WHT_Get_Curr_Data_Count)(const WHT_DMA_Config_t* config);//获取当前DMA传输个数
    void (*WHT_Close)(const WHT_DMA_Config_t* config);                  //DMA关闭
}WHT_DMA_BSP_t;

/*全局常量*/
extern const WHT_DMA_BSP_t WHT_DMA_BSP;

/*DMA内存拷贝API*/
extern void WHT_DMA_BSP_Memcpy(void* _Dst, void const* _Src, unsigned int _Size);//无法知道传输的状态

#endif // !__DMA_BSP_H__
